使用OpenCV获取物体的骨架

您所在的位置:网站首页 Empty of what 使用OpenCV获取物体的骨架

使用OpenCV获取物体的骨架

#使用OpenCV获取物体的骨架| 来源: 网络整理| 查看: 265

概述

在很多计算机视觉的应用里,都需要处理大量的数据,耗时费内存。为了减少处理时间,降低内存占用,需要使用物体的紧凑表示,也就是物体的骨架(skeleton)。

物体的骨架要求能够表示这个形状的结构,删除多余的像素点,下图是字母B的骨架。

这篇文章介绍一种使用OpenCV库计算生态骨架(morphological  skeleton)的方法,这种方法简单实用。维基百科中有介绍说通过腐蚀和膨胀操作就可以获得morphological  skeleton,伪代码如下:

img = ...; while (not_empty(img)) { skel = skel | (img & !open(img)); img = erosion(img); }

说明一下算法的原理

每次迭代图像都会再次腐蚀,经过腐蚀后物体变得更窄细对腐蚀后图像做开运算,经过开运算后处理后,图像有些像素会被删除,这些被删除的像素其实是骨架的一部分将删除的像素,添加到骨架图上当腐蚀后图像没有像素后后,就结束跌打,这时候或生成的骨架图也就完整了 python实现 import os import numpy as np import cv2 import sys im_path = sys.argv[1] im = cv2.imread(im_path, 0) if im is None: print im_path, " not exist" sys.exit() ret, im = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY) element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) skel = np.zeros(im.shape, np.uint8) temp = np.zeros(im.shape, np.uint8) i = 0 while True: cv2.imshow('im %d'%(i), im) #取开运算过程中消失的像素,这些像素便是skeleton的一部分 temp = cv2.morphologyEx(im, cv2.MORPH_OPEN, element) temp = cv2.bitwise_not(temp) temp = cv2.bitwise_and(im, temp) cv2.imshow('skeleton part %d'%(i,), temp) #将删除的像素添加skeleton图中 skel = cv2.bitwise_or(skel, temp) #再次腐蚀原图,为进一步寻找skeleton做准备 im = cv2.erode(im, element) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(im) #print min_val, max_val, min_loc, max_loc if max_val==.0: break i += 1 cv2.imshow('Skeleton', skel) cv2.waitKey()

实验效果:

上图中im0 -4表示每轮迭代是经过腐蚀后的图片,skeleton part 0-4表示经过开源获得的骨架像素,最后这些像素组合在一起获得骨架图skeleton,很神奇的。

性能优化

之前的实现里,使用openning运算,开运算后有对原图做了erode操作。实际上opening运算是erode + dilate,所以进行了两次腐蚀,有重复计算,可以只使用一次。另外minMaxLoc()函数函数效率比countNonZero()要慢。优化后代码如下:

import os import numpy as np import cv2 import sys im_path = sys.argv[1] im = cv2.imread(im_path, 0) if im is None: print im_path, " not exist" sys.exit() ret, im = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY) element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) skel = np.zeros(im.shape, np.uint8) erode = np.zeros(im.shape, np.uint8) temp = np.zeros(im.shape, np.uint8) i = 0 while True: cv2.imshow('im %d'%(i), im) erode = cv2.erode(im,element) temp = cv2.dilate(erode, element) #消失的像素是skeleton的一部分 temp = cv2.subtract(im, temp) cv2.imshow('skeleton part %d' %(i,), temp) skel = cv2.bitwise_or(skel, temp) im = erode.copy() if cv2.countNonZero(im)== 0: break; i += 1 cv2.imshow('Skeleton', skel) cv2.waitKey() 参考

http://felix.abecassis.me/2011/09/opencv-morphological-skeleton/



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3